package com.wu.dms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wu.common.convertion.errorcode.SongErrorCode;
import com.wu.common.convertion.exception.ServiceException;
import com.wu.dms.dao.entity.Song;
import com.wu.dms.dao.mapper.SongMapper;
import com.wu.dms.dto.SongRequestDTO;
import com.wu.dms.service.SongService;
import com.wu.constant.Enum.MinIoNameEnum;
import com.wu.dms.util.MinIoUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class SongServiceImpl extends ServiceImpl<SongMapper, Song> implements SongService {

    private final MinIoUtil minIoUtil;

    @SneakyThrows
    @Override
    public void addSong(SongRequestDTO addSongRequestDTO, MultipartFile file) {
        Song song = new Song();
        BeanUtils.copyProperties(addSongRequestDTO, song);
        String fileName = file.getOriginalFilename();
        song.setCreateTime(new Date());
        song.setUpdateTime(new Date());
        song.setPic(MinIoNameEnum.SINGER_IMAGE.getDefaultObjectName());
        song.setUrl(fileName);
        save(song);
        minIoUtil.uploadFile(MinIoNameEnum.SONG.getBucketName(), song.getId()+"-"+fileName,file.getInputStream(),file.getSize());
    }

    @Transactional
    @Override
    @Async
    public void updateSongMsg(SongRequestDTO updateSongRequestDTO) {
        Song song = BeanUtil.toBean(updateSongRequestDTO, Song.class);
        try {
            updateById(song);
        } catch (Exception e) {
            throw new ServiceException(SongErrorCode.SONG_UPDATE_ERROR);
        }

    }

    @SneakyThrows
    @Transactional
    @Override
    public void updateSongUrl(MultipartFile file, Long id) {

        Song song = query().eq("id", id).one();
        if (song==null){
            return;
        }
        String originFileName = song.getUrl();
        minIoUtil.deleteFile(MinIoNameEnum.SONG.getBucketName(), MinIoNameEnum.getDefaultObjectName(song.getId(),originFileName));

        String fileName = file.getOriginalFilename();
        LambdaUpdateWrapper<Song> updateWrapper = Wrappers.lambdaUpdate(Song.class)
                .eq(Song::getId, id)
                .set(Song::getUrl, fileName);
        minIoUtil.uploadFile(MinIoNameEnum.SONG.getBucketName(), MinIoNameEnum.getDefaultObjectName(id,fileName),file.getInputStream(),file.getSize());
        this.update(updateWrapper);
    }


    @SneakyThrows
    @Override
    public void updateSongPic(MultipartFile file, Long id) {
        String filename = file.getOriginalFilename();
        if (MinIoNameEnum.SONG_IMAGE.getDefaultObjectName().equals(filename)){
            return;
        }
        Song song = query().eq("id", id).one();
        if (song == null) {
            return;
        }
        String originImageFileName = song.getPic();
        minIoUtil.deleteFile(MinIoNameEnum.SONG_IMAGE.getBucketName(), originImageFileName);
        minIoUtil.uploadFile(MinIoNameEnum.SONG_IMAGE.getBucketName(), MinIoNameEnum.getDefaultObjectName(id,filename),file.getInputStream(),file.getSize());
        LambdaUpdateWrapper<Song> updateWrapper = Wrappers.lambdaUpdate(Song.class)
                .eq(Song::getId, id)
                .set(Song::getPic, filename);
        if (!update(updateWrapper)) {
            throw new ServiceException(SongErrorCode.SONG_UPDATE_IMAGE_ERROR);
        }
    }

    @SneakyThrows
    @Override
    public void deleteSong(Long id) {
        String bucketName = "img";
        String originImageFileName = "song-"+query().eq("id", id).one().getPic()+"-"+id;
        minIoUtil.deleteFile(bucketName, originImageFileName);
        if (!removeById(id)) {
            throw new ServiceException(SongErrorCode.SONG_DELETE_ERROR);
        }

    }


    @Override
    public List<Song> songOfSingerId(Long singerId) {
        String bucketName = "img";
        List<Song> songs = query().eq("singer_id", singerId).list();
        for (Song song : songs) {
            String finalFileName = "song-"+song.getPic()+"-"+song.getId();
            try {
                String imgUrl = minIoUtil.getFileUrlWithTime(bucketName, finalFileName, 30, TimeUnit.MINUTES);
                song.setPic(imgUrl);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return songs;
    }

    @Override
    public List<Song> songOfId(Long id) {
        return query().eq("id", id).list();
    }

    @Override
    public List<Song> songOfSingerName(String name) {


        return query().like("name", name).list();
    }

}
